home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / nihcl-30.lha / nihcl-3.0 / lib / Object.c < prev    next >
C/C++ Source or Header  |  1990-05-19  |  8KB  |  318 lines

  1. /* Object.c -- implementation of class Object
  2.  
  3.     THIS SOFTWARE FITS THE DESCRIPTION IN THE U.S. COPYRIGHT ACT OF A
  4.     "UNITED STATES GOVERNMENT WORK".  IT WAS WRITTEN AS A PART OF THE
  5.     AUTHOR'S OFFICIAL DUTIES AS A GOVERNMENT EMPLOYEE.  THIS MEANS IT
  6.     CANNOT BE COPYRIGHTED.  THIS SOFTWARE IS FREELY AVAILABLE TO THE
  7.     PUBLIC FOR USE WITHOUT A COPYRIGHT NOTICE, AND THERE ARE NO
  8.     RESTRICTIONS ON ITS USE, NOW OR SUBSEQUENTLY.
  9.  
  10. Author:
  11.     K. E. Gorlen
  12.     Bg. 12A, Rm. 2033
  13.     Computer Systems Laboratory
  14.     Division of Computer Research and Technology
  15.     National Institutes of Health
  16.     Bethesda, Maryland 20892
  17.     Phone: (301) 496-1111
  18.     uucp: uunet!nih-csl!kgorlen
  19.     Internet: kgorlen@alw.nih.gov
  20.     September, 1985
  21.  
  22. Function:
  23.  
  24. Operations applicable to all objects.
  25.     
  26. $Log:    Object.c,v $
  27.  * Revision 3.0  90/05/20  00:20:35  kgorlen
  28.  * Release for 1st edition.
  29.  * 
  30. */
  31.  
  32. #include <ctype.h>
  33. #include <string.h>
  34. #include "nihclconfig.h"
  35. #include "nihclIO.h"
  36. #include "OIOTbl.h"
  37. #include "Object.h"
  38. #include "Dictionary.h"
  39. #include "LookupKey.h"
  40. #include "IdentDict.h"
  41. #include "IdentSet.h"
  42. #include "String.h"
  43. #include "Assoc.h"
  44. #include "AssocInt.h"
  45. #include "OrderedCltn.h"
  46.  
  47. extern const int NIHCL_AMBIGCASTDN,NIHCL_DRVDCLASSRSP,NIHCL_ILLEGALMFCN,NIHCL_BADARGCL,
  48.     NIHCL_BADARGSP,NIHCL_BADARGCLM,NIHCL_BADARGSPM,NIHCL_BADCASTDN,NIHCL_BADCLASS,
  49.     NIHCL_BADSTMBR,NIHCL_BADSPEC,NIHCL_NOISA,NIHCL_RDABSTCLASS;
  50.  
  51. #define    THIS    Object
  52. #define    BASE_CLASSES
  53. #define MEMBER_CLASSES
  54. #define VIRTUAL_BASE_CLASSES
  55.  
  56. /* DEFINE_CLASS(); */
  57.  
  58. Object* Object::reader(OIOin&)
  59. {
  60.     setError(NIHCL_RDABSTCLASS,DEFAULT,"Object");
  61.     return 0;
  62. }
  63.  
  64. Object* Object::reader(OIOifd&)
  65. {
  66.     setError(NIHCL_RDABSTCLASS,DEFAULT,"Object");
  67.     return 0;
  68. }
  69.  
  70. static Class class_Object("Object",
  71.     ClassList(0,0), ClassList(0,0), ClassList(0,0),
  72.     1,    // version
  73.     "$Header: /afs/alw.nih.gov/unix/sun4_40c/usr/local/src/nihcl-3.0/share/lib/RCS/Object.c,v 3.0 90/05/20 00:20:35 kgorlen Rel $",
  74.     sizeof(Object), Object::reader, Object::reader, NULL, NULL );
  75.  
  76. const Class* Object::desc()    { return &class_Object; }
  77.  
  78. void* Object::_castdown(const Class& target) const
  79. {
  80.     if (&target == &class_Object) return (void*)this;
  81.     return 0;
  82. }
  83.  
  84. void* Object::_safe_castdown(const Class& target) const
  85. {
  86.     void* p = _castdown(target);
  87.     if (p == 0) setError(NIHCL_BADCASTDN,DEFAULT,this,className(),target.name());
  88.     return p;
  89. }
  90.  
  91. void Object::ambigCheck(void*& p, void*& q, const Class& target) const
  92. {
  93.     if (p == 0 || p == q) return;
  94.     if (q == 0) { q = p;  return; }
  95.     setError(NIHCL_AMBIGCASTDN,DEFAULT,this,className(),target.name());
  96. }
  97.  
  98. bool Object::isKindOf(const Class& clid) const
  99. {
  100.     return isA()->_isKindOf(clid);
  101. }
  102.  
  103. unsigned Object::size() const { return 0; }
  104.  
  105. unsigned Object::capacity() const { return 0; }
  106.  
  107. const Class* Object::species() const    { return isA(); }
  108.  
  109. Object* Object::copy() const { return shallowCopy(); }
  110.  
  111. static IdentDict* deepCopyDict =0;    // object ID -> object copy dictionary for deepCopy()
  112. static IdentSet* deepCopyVBaseSet =0;    // deepened virtual base set for deepCopy()
  113.  
  114. Object* Object::deepCopy() const
  115. {
  116.     bool firstObject = NO;
  117.     if (deepCopyDict == 0) {
  118.         deepCopyDict = new IdentDict;
  119.         deepCopyDict->add(*new Assoc(*nil,*nil));
  120.         firstObject = YES;
  121.     }
  122.     Assoc* asc = (Assoc*)deepCopyDict->assocAt(*this);
  123.     if (asc == 0) {                // object has not been copied 
  124.         Object* copy = shallowCopy();    // make a shallow copy 
  125.         deepCopyDict->add(*new Assoc(*(Object*)this,*copy));    // add to dictionary 
  126.         copy->deepenShallowCopy();    // convert shallow copy to deep copy 
  127.         if (firstObject) {        // delete the deepCopy dictionary 
  128.             DO(*deepCopyDict,Assoc,asc) delete asc; OD
  129.             delete deepCopyDict;
  130.             deepCopyDict = 0;
  131.             delete deepCopyVBaseSet;  // and the deepen VBase IdentSet
  132.             deepCopyVBaseSet = 0;
  133.         }
  134.         return copy;
  135.     }
  136.     else return asc->value();    // object already copied, just return object reference 
  137. }
  138.  
  139. bool Class::_deepenVBase(void* p)
  140. {
  141.     if (deepCopyVBaseSet == 0) {
  142.         deepCopyVBaseSet = new IdentSet(256);
  143.         deepCopyVBaseSet->add(*(Object*)p);
  144.         return YES;
  145.     }
  146.     if (deepCopyVBaseSet->includes(*(Object*)p)) return NO;
  147.     deepCopyVBaseSet->add(*(Object*)p);
  148.     return YES;
  149. }
  150.  
  151. // error reporting 
  152.  
  153. void Object::derivedClassResponsibility(const char* fname) const
  154. {
  155.     setError(NIHCL_DRVDCLASSRSP,DEFAULT,this,className(),fname);
  156. }
  157.  
  158. void Object::destroyer() {}
  159.  
  160. void Object::shouldNotImplement(const char* fname) const
  161. {
  162.     setError(NIHCL_ILLEGALMFCN,DEFAULT,this,className(),fname);
  163. }
  164.  
  165. void Object::invalidArgClass(const Class& expect, const char* fname) const
  166. {
  167.     setError(NIHCL_BADARGCL,DEFAULT,fname,expect.name(),fname,className());
  168. }
  169.  
  170. void Object::invalidArgClass(const Object& ob, const Class& expect, const char* fname) const
  171. {
  172.     setError(NIHCL_BADARGCLM,DEFAULT,className(),fname,expect.name(),className(),fname,ob.className());
  173. }
  174.  
  175. void Object::invalidArgSpecies(const Class& expect, const char* fname) const
  176. {
  177.     setError(NIHCL_BADARGSP,DEFAULT,fname,expect.name(),fname,species()->className());
  178. }
  179.  
  180. void Object::invalidArgSpecies(const Object& ob, const Class& expect, const char* fname) const
  181. {
  182.     setError(NIHCL_BADARGSPM,DEFAULT,className(),fname,expect.name(),className(),fname,ob.species()->name());
  183. }
  184.  
  185. void Object::invalidClass(const Class& expect) const
  186. {
  187.     setError(NIHCL_BADCLASS,DEFAULT,expect.name(),className());
  188. }
  189.  
  190. void Object::invalidSpecies(const Class& expect) const
  191. {
  192.     setError(NIHCL_BADSPEC,DEFAULT,expect.name(),species()->name());
  193. }
  194.  
  195. void Object::dumpOn(ostream& strm) const
  196. {
  197.     strm << className() << '[';
  198.     printOn(strm);
  199.     strm << ']' << endl;
  200. }
  201.  
  202. void Object::scanFrom(istream&) { derivedClassResponsibility("scanFrom"); }
  203.  
  204. // Object I/O
  205.  
  206. class StoreOnTblMgr {
  207.     friend void Object::storeOn(OIOout& strm) const;
  208.     friend void Object::storeOn(OIOofd& fd) const;
  209.     StoreOnTblMgr() {
  210.         if (Class::storeOn_level++ == 0) Class::storeOnTbl = new StoreOnTbl;
  211.     }
  212.     ~StoreOnTblMgr() {
  213.         if (--Class::storeOn_level == 0) {
  214.             delete Class::storeOnTbl;
  215.             Class::storeOnTbl = 0;
  216.             delete Class::storeVBaseTbl;
  217.             Class::storeVBaseTbl = 0;
  218.         }
  219.     }
  220. };
  221.  
  222. void Object::storeOn(OIOout& strm) const
  223. {
  224.     StoreOnTblMgr tbl;
  225.     strm.storeObject(*this);
  226. }
  227.  
  228. void Object::storeMemberOn(OIOout& strm) const
  229. {
  230.     if (Class::storeOnLevel() == 0) setError(NIHCL_BADSTMBR,DEFAULT,this,className());
  231.     Class::storeOnTbl->addMember(*this);
  232.     storer(strm);
  233. }
  234.  
  235.  
  236. void Object::storer(OIOout& /*strm*/) const    // store class Object 
  237. {
  238. }
  239.  
  240. // binary object I/O
  241.  
  242. void Object::storeOn(OIOofd& fd) const
  243. {
  244.     StoreOnTblMgr tbl;
  245.     fd.storeObject(*this);
  246. }
  247.  
  248. void Object::storeMemberOn(OIOofd& fd) const
  249. {
  250.     if (Class::storeOnLevel() == 0) setError(NIHCL_BADSTMBR,DEFAULT,this,className());
  251.     Class::storeOnTbl->addMember(*this);
  252.     storer(fd);
  253. }
  254.  
  255. void Object::storer(OIOofd& /*fd*/) const    // store Object on file descriptor
  256. {
  257. }
  258.  
  259. // Object Dependence Relationships 
  260.  
  261. static IdentDict* dependDict =0;    // object ID -> dependents list 
  262.     
  263. Object* Object::addDependent(Object& ob)
  264. {
  265.     if (dependDict == 0) dependDict = new IdentDict;
  266.     if (!(dependDict->includesKey(*this)))
  267.         dependDict->add(*new Assoc(*this,*new OrderedCltn));
  268.     OrderedCltn::castdown(dependDict->atKey(*this))->add(ob);
  269.     return &ob;
  270. }
  271.  
  272. Object* Object::removeDependent(const Object& ob)
  273. {
  274.     if (dependDict == 0) return nil;
  275.     Object* val = dependDict->atKey(*this);
  276.     if (val == nil) return nil;
  277.     OrderedCltn* depList = OrderedCltn::castdown(val);
  278.     Object* dependent = depList->removeId(ob);
  279.     if (depList->size() == 0) release();
  280.     return dependent;
  281. }
  282.     
  283. OrderedCltn& Object::dependents() const
  284. {
  285.     if (dependDict == 0) return *new OrderedCltn(1);
  286.     Assoc* asc = (Assoc*)dependDict->assocAt(*this);
  287.     if (asc == 0) return *new OrderedCltn(1);
  288.     return *new OrderedCltn(*OrderedCltn::castdown(asc->value()));
  289. }
  290.     
  291. void Object::release()
  292. {
  293.     if (dependDict != 0 && dependDict->includesKey(*this)) {
  294.         Assoc* asc = (Assoc*)dependDict->removeKey(*this);
  295.         OrderedCltn* oc = OrderedCltn::castdown(asc->value());
  296.         delete oc;
  297.         delete asc;
  298.         if (dependDict->size() == 0) {
  299.             delete dependDict;
  300.             dependDict = 0;
  301.         }
  302.     }
  303. }
  304.  
  305. void Object::changed(const Object& param)
  306. {
  307.     OrderedCltn* depList = &dependents();
  308.     DO(*depList,Object,depob) depob->update(*this,param); OD
  309.     delete depList;
  310. }
  311.  
  312. void Object::changed()    { changed(*nil); }
  313.  
  314. void Object::update(const Object& /*dependent*/, const Object& /*param*/)
  315. {
  316.     derivedClassResponsibility("update");
  317. }
  318.